/**
 * html+ 多设备串口蓝牙操作
 */
function createMultiBluetoothTool() {
	let BluetoothAdapter = plus.android.importClass("android.bluetooth.BluetoothAdapter");
	let Intent = plus.android.importClass("android.content.Intent");
	let IntentFilter = plus.android.importClass("android.content.IntentFilter");
	let BluetoothDevice = plus.android.importClass("android.bluetooth.BluetoothDevice");
	let Build = plus.android.importClass("android.os.Build");
	let UUID = plus.android.importClass("java.util.UUID");
	let Toast = plus.android.importClass("android.widget.Toast");
	//连接串口设备的 UUID
	let MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

	let invoke = plus.android.invoke;
	let btAdapter = BluetoothAdapter.getDefaultAdapter();
	let activity = plus.android.runtimeMainActivity();

	// 多设备连接管理
	let deviceConnections = new Map(); // 存储多个设备连接
	let btFindReceiver = null; //蓝牙搜索广播接收器
	let btStatusReceiver = null; //蓝牙状态监听广播

	let state = {
		bluetoothEnable: false, //蓝牙是否开启
		bluetoothState: "", //当前蓝牙状态
		discoveryDeviceState: false, //是否正在搜索蓝牙设备
		connectedDevices: [], //已连接设备列表
	};

	let options = {
		/**
		 * 监听蓝牙状态回调
		 * @param {String} state
		 */
		listenBTStatusCallback: function(state) {},
		/**
		 * 搜索到新的蓝牙设备回调
		 * @param {Device} newDevice
		 */
		discoveryDeviceCallback: function(newDevice) {},
		/**
		 * 停止搜索回调
		 */
		cancelDiscoveryCallback: function() {},
		/**
		 * 蓝牙搜索完成回调
		 */
		discoveryFinishedCallback: function() {},
		/**
		 * 接收到数据回调
		 * @param {String} deviceAddress 设备地址
		 * @param {Array} dataByteArr 数据
		 */
		readDataCallback: function(deviceAddress, dataByteArr) {},
		/**
		 * 蓝牙连接中断回调
		 * @param {String} deviceAddress 设备地址
		 * @param {Exception} e 异常
		 */
		connExceptionCallback: function(deviceAddress, e) {},
		/**
		 * 设备连接成功回调
		 * @param {String} deviceAddress 设备地址
		 */
		deviceConnectedCallback: function(deviceAddress) {},
		/**
		 * 设备断开连接回调
		 * @param {String} deviceAddress 设备地址
		 */
		deviceDisconnectedCallback: function(deviceAddress) {}
	}

	let multiBluetoothToolInstance = {
		state: state, //蓝牙状态
		init: init, //初始化回调函数
		isSupportBluetooth: isSupportBluetooth,
		getBluetoothStatus: getBluetoothStatus,
		turnOnBluetooth: turnOnBluetooth,
		turnOffBluetooth: turnOffBluetooth,
		getPairedDevices: getPairedDevices,
		discoveryNewDevice: discoveryNewDevice,
		listenBluetoothStatus: listenBluetoothStatus,
		connDevice: connDevice,
		disConnDevice: disConnDevice,
		disConnAllDevices: disConnAllDevices,
		cancelDiscovery: cancelDiscovery,
		sendData: sendData,
		getConnectedDevices: getConnectedDevices,
		isDeviceConnected: isDeviceConnected
	}
	
	if (window.multiBluetoothToolInstance) {
		return window.multiBluetoothToolInstance;
	} else {
		window.multiBluetoothToolInstance = multiBluetoothToolInstance;
		return multiBluetoothToolInstance;
	}

	function init(setOptions) {
		Object.assign(options, setOptions);
		//6.0以后的如果需要利用本机查找周围的wifi和蓝牙设备, 申请权限
		if (Build.VERSION.SDK_INT >= 6.0) {
			console.log('申请权限')
			requestPermission()
		}
		state.bluetoothEnable = getBluetoothStatus();
		listenBluetoothStatus();
	}

	function shortToast(msg) {
		plus.nativeUI.toast(msg);
	}

	/**
	 * 是否支持蓝牙
	 * @return {boolean}
	 */
	function isSupportBluetooth() {
		if (btAdapter != null) {
			return true;
		}
		return false;
	}
	
	/**
	 * 获取蓝牙的状态
	 * @return {boolean} 是否已开启
	 */
	function getBluetoothStatus() {
		if (btAdapter != null) {
			return btAdapter.isEnabled();
		}
		return false;
	}

	/**
	 * 打开蓝牙
	 */
	function turnOnBluetooth() {
		if (btAdapter == null) {
			shortToast("没有蓝牙");
			return;
		}
		if (!btAdapter.isEnabled()) {
			if (activity == null) {
				shortToast("未获取到activity");
				return;
			} else {
				let intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
				let requestCode = 1;
				activity.startActivityForResult(intent, requestCode);
				return;
			}
		} else {
			shortToast("蓝牙已经打开");
		}
	}

	/**
	 * 关闭蓝牙
	 */
	function turnOffBluetooth() {
		if (btAdapter != null && btAdapter.isEnabled()) {
			btAdapter.disable();
		}
		if (btFindReceiver != null) {
			try {
				activity.unregisterReceiver(btFindReceiver);
			} catch (e) {
			}
			btFindReceiver = null;
		}
		state.bluetoothEnable = false;
		cancelDiscovery();
		disConnAllDevices();

		if (btAdapter != null && btAdapter.isEnabled()) {
			btAdapter.disable();
			shortToast("蓝牙关闭成功");
		} else {
			shortToast("蓝牙已经关闭");
		}
	}

	/**
	 * 获取已经配对的设备
	 * @return {Array} connetedDevices
	 */
	function getPairedDevices() {
		let pairedDevices = [];

		//蓝牙连接android原生对象，是一个set集合
		let pairedDevicesAndroid = null;
		if (btAdapter != null && btAdapter.isEnabled()) {
			pairedDevicesAndroid = btAdapter.getBondedDevices();
		} else {
			shortToast("蓝牙未开启");
		}

		if (!pairedDevicesAndroid) {
			return pairedDevices;
		}

		//遍历连接设备的set集合，转换为js数组
		let it = invoke(pairedDevicesAndroid, "iterator");
		while (invoke(it, "hasNext")) {
			let device = invoke(it, "next");
			pairedDevices.push({
				"name": invoke(device, "getName"),
				"address": invoke(device, "getAddress")
			});
		}
		return pairedDevices;
	}

	/**
	 * 发现设备
	 */
	function discoveryNewDevice() {
		console.log('开始扫描设备', btFindReceiver)
		if (btFindReceiver != null) {
			try {
				activity.unregisterReceiver(btFindReceiver);
			} catch (e) {
				console.error('扫描设备发生错误', e);
			}
			btFindReceiver = null;
			cancelDiscovery();
		}

		btFindReceiver = plus.android.implements("io.dcloud.android.content.BroadcastReceiver", {
			onReceive: function(context, intent) {
				plus.android.importClass(intent);
				let action = intent.getAction();
				console.log('接收到发现设备广播消息', action)
				if (BluetoothDevice.ACTION_FOUND == action) { // 找到设备
					let device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
					let newDevice = {
						"name": plus.android.invoke(device, "getName"),
						"address": plus.android.invoke(device, "getAddress")
					}
					options.discoveryDeviceCallback && options.discoveryDeviceCallback(newDevice);
				}
				if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED == action) { // 搜索完成
					cancelDiscovery();
					options.discoveryFinishedCallback && options.discoveryFinishedCallback();
				}
			}
		});

		let filter = new IntentFilter();
		filter.addAction(BluetoothDevice.ACTION_FOUND);
		filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
		console.log('注册发现设备Receiver');
		activity.registerReceiver(btFindReceiver, filter);
		console.log('开始搜索');
		btAdapter.startDiscovery(); //开启搜索
		state.discoveryDeviceState = true;
	}

	/**
	 * 蓝牙状态监听
	 */
	function listenBluetoothStatus() {
		if (btStatusReceiver != null) {
			try {
				activity.unregisterReceiver(btStatusReceiver);
			} catch (e) {
				console.error(e);
			}
			btStatusReceiver = null;
		}

		btStatusReceiver = plus.android.implements("io.dcloud.android.content.BroadcastReceiver", {
			"onReceive": function(context, intent) {
				plus.android.importClass(context);
				plus.android.importClass(intent);

				let action = intent.getAction();
				switch (action) {
					case BluetoothAdapter.ACTION_STATE_CHANGED:
						let blueState = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
						console.log('蓝牙工具', blueState)
						let stateStr = "";
						switch (blueState) {
							case BluetoothAdapter.STATE_TURNING_ON:
								stateStr = "STATE_TURNING_ON";
								break;
							case BluetoothAdapter.STATE_ON:
								state.bluetoothEnable = true;
								stateStr = "STATE_ON";
								break;
							case BluetoothAdapter.STATE_TURNING_OFF:
								stateStr = "STATE_TURNING_OFF";
								break;
							case BluetoothAdapter.STATE_OFF:
								stateStr = "STATE_OFF";
								state.bluetoothEnable = false;
								break;
						}
						state.bluetoothState = stateStr;
						options.listenBTStatusCallback && options.listenBTStatusCallback(stateStr);
						break;
				}
			}
		});
		let filter = new IntentFilter();
		filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
		activity.registerReceiver(btStatusReceiver, filter);
	}

	/**
	 * 根据蓝牙地址，连接设备
	 * @param {String} address
	 * @return {Boolean}
	 */
	function connDevice(address) {
		let InputStream = plus.android.importClass("java.io.InputStream");
		let OutputStream = plus.android.importClass("java.io.OutputStream");
		let BluetoothSocket = plus.android.importClass("android.bluetooth.BluetoothSocket");

		// 检查设备是否已连接
		if (deviceConnections.has(address)) {
			shortToast("设备已连接");
			return true;
		}

		try {
			let device = invoke(btAdapter, "getRemoteDevice", address);
			let btSocket = invoke(device, "createRfcommSocketToServiceRecord", MY_UUID);
			
			// 连接设备
			invoke(btSocket, "connect");
			
			// 创建数据流
			let btInStream = invoke(btSocket, "getInputStream");
			let btOutStream = invoke(btSocket, "getOutputStream");
			
			// 存储设备连接信息
			deviceConnections.set(address, {
				socket: btSocket,
				inStream: btInStream,
				outStream: btOutStream,
				readThreadState: true,
				setIntervalId: null
			});
			
			// 启动数据读取线程
			startReadData(address);
			
			// 更新状态
			state.connectedDevices.push(address);
			
			shortToast("连接成功");
			options.deviceConnectedCallback && options.deviceConnectedCallback(address);
			
		} catch (e) {
			console.error(e);
			shortToast("连接失败");
			return false;
		}
		
		cancelDiscovery();
		return true;
	}

	/**
	 * 启动数据读取线程
	 * @param {String} deviceAddress
	 */
	function startReadData(deviceAddress) {
		let connection = deviceConnections.get(deviceAddress);
		if (!connection) return;
		
		let btInStream = connection.inStream;
		let btOutStream = connection.outStream;
		let setTimeCount = 0;
		
		function read() {
			clearInterval(connection.setIntervalId);
			connection.setIntervalId = setInterval(function() {
				setTimeCount++;
				if (connection.readThreadState) {
					// 心跳检测
					if (setTimeCount % 20 == 0) {
						try {
							btOutStream.write([0b00]);
						} catch (e) {
							connection.readThreadState = false;
							options.connExceptionCallback && options.connExceptionCallback(deviceAddress, e);
						}
					}
					
					let dataArr = [];
					while (invoke(btInStream, "available") !== 0) {
						let data = invoke(btInStream, "read");
						dataArr.push(data);
					}
					if (dataArr.length > 0) {
						options.readDataCallback && options.readDataCallback(deviceAddress, dataArr);
					}
				}
			}, 40);
		}
		
		read();
	}

	/**
	 * 断开指定设备连接
	 * @param {String} deviceAddress
	 * @return {Boolean}
	 */
	function disConnDevice(deviceAddress) {
		let connection = deviceConnections.get(deviceAddress);
		if (connection) {
			connection.readThreadState = false;
			if (connection.setIntervalId) {
				clearInterval(connection.setIntervalId);
			}
			try {
				connection.socket.close();
			} catch (e) {
				console.error(e);
			}
			deviceConnections.delete(deviceAddress);
			
			// 从状态中移除
			let index = state.connectedDevices.indexOf(deviceAddress);
			if (index > -1) {
				state.connectedDevices.splice(index, 1);
			}
			
			options.deviceDisconnectedCallback && options.deviceDisconnectedCallback(deviceAddress);
			shortToast("断开连接成功");
			return true;
		}
		return false;
	}

	/**
	 * 断开所有设备连接
	 */
	function disConnAllDevices() {
		for (let [address, connection] of deviceConnections) {
			disConnDevice(address);
		}
		deviceConnections.clear();
		state.connectedDevices = [];
	}

	/**
	 * 取消发现
	 */
	function cancelDiscovery() {
		console.log('停止扫描设备')
		if (btAdapter.isDiscovering()) {
			btAdapter.cancelDiscovery();
			options.cancelDiscoveryCallback && options.cancelDiscoveryCallback();
		}
		if (btFindReceiver != null) {
			activity.unregisterReceiver(btFindReceiver);
			btFindReceiver = null;
		}
		state.discoveryDeviceState = false;
	}

	/**
	 * 发送数据到指定设备
	 * @param {String} deviceAddress 设备地址
	 * @param {Array} bytes 数据字节数组
	 * @return {Boolean}
	 */
	function sendData(deviceAddress, bytes) {
		console.log('写入蓝牙数据到设备', deviceAddress, bytes);
		let connection = deviceConnections.get(deviceAddress);
		if (!connection || !connection.outStream) {
			shortToast("设备未连接");
			return false;
		}
		
		try {
			connection.outStream.write(bytes);
		} catch (e) {
			console.error('写入蓝牙数据错误', e);
			return false;
		}
		return true;
	}

	/**
	 * 获取已连接设备列表
	 * @return {Array}
	 */
	function getConnectedDevices() {
		return state.connectedDevices;
	}

	/**
	 * 检查设备是否已连接
	 * @param {String} deviceAddress
	 * @return {Boolean}
	 */
	function isDeviceConnected(deviceAddress) {
		return deviceConnections.has(deviceAddress);
	}
} 